<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

正则：用来处理（匹配）字符串的；正则是一套单独的语法体系

元字符：在正则当中有特殊语义的字符：[] [^] ? * + {min,max} ^ $ () \1\2 |;

1. 字符串组：[]范围；在固定范围内匹配一个；注意字符组的顺序；[^]范围取反
简写：\d [0-9] \D [^0-9]
\w [0-9A-Za-z] \W[^0-9A-Za-z]
\s [\f\n\r\t] \S[^\f\n\r\t]

2. 量词；匹配多个；修饰个数
{n} 匹配n次
{n,m} 匹配最少n次，最多m次
{n,} 匹配最少n次，最多无限制
简写：
? {0,1}
* {0,}
+ {1,}

**正则是贪婪的，贪婪模式，能躲就躲**

非贪婪模式在量词后面加?

3.() 作用：1.分组；子表达式
          2.引用；捕获；
          3.反向引用
          4.非捕获 ?:

4. | 作用： 选择或者关系；自左向右匹配一旦匹配就不在回头

5.断言；\b \B (判断是不是以正则开头或者结尾)

6.环视

7.匹配模式 g(global 全局匹配) i(ignore case 忽略大小写) m(multiply 多行匹配)

8.匹配优先级

<body>
  <script>
    // console.log(/\+/.test('+'))

    // console.log(/[123456789]/.test('3'));
    // 用-连接的字符串范围必须符合ASCII码顺序 
    // console.log(/[1-9]/.test('133'));
    // console.log(/[a-z]/.test('a'));
    // console.log(/[A-Z]/.test('Z'));

    // 9-1直接报错
    // console.log(/[9-1]/.test('1')); 

    // 组合与组合之间没必要按照顺序
    // console.log(/[0-9a-zA-Z]/.test('1aZ'));
    // [^0-9] 尖角号是取反的意思
    // console.log(/[^0-9]/.test('a')); // true

    // console.log(/[0-9][0-9][0-9][0-9][0-9][0-9]/.test('123456'));
    // console.log(/\d\d\d\d\d\d/.test('123456'));

    // 量词{1,3} 之间不能有空格 空格在正则中有其他含义
    // 贪婪模式 能多就多
    // console.log(/\d{6}/.test(6654125));
    // exec能看出是哪一位开始匹配
    // console.log(/\d{6}/.exec(6654125));
    // console.log(/\d{1,5}/.exec(6654125));
    // console.log(/\d{0,1}/.exec(6654125));
    // console.log(/\d{1,}/.exec(6654125));

    // 简写
    // console.log(/a{1,}/.exec('aaaaaa'));
    // console.log(/a+/.exec('aaaaaa'));

    // console.log(/a{0,1}/.exec('aaaaaa'));
    // console.log(/a?/.exec('aaaaaa'));

    // console.log(/a{0,}/.exec('aaaaaa'));
    // console.log(/a*/.exec('aaaaaa'));

    // 非贪婪模式  能少就少
    // console.log(/a+?/.exec('aaaaaa')); // a
    // console.log(/a*?/.exec('aaaaaa')); // a
    // console.log(/a??/.exec('aaaaaa')); // ''

    // .匹配出了\n换行符以外所有字符
    // console.log(/./.exec('a'));

    // ()
    // console.log(/(ab){2}/.exec('abab'));

    // console.log(/(\d{4})-(\d{1,2})-(\d{1,2})/.exec('2020-10-31'));
    // console.log(/(\d{4})-(\d{1,2})-(\d{1,2})/.exec('2020-10-31')[1]);
    // console.log(/(\d{4})-(\d{1,2})-(\d{1,2})/.exec('2020-10-31')[2]);
    // console.log(/(\d{4})-(\d{1,2})-(\d{1,2})/.exec('2020-10-31')[3]);

    // \1 \2 代表匹配到的元素
    // console.log(/[a-z]{2}/.exec('ab'));
    // console.log(/([a-z])\1/.exec('bb'));

    // <h1><h1></h1></h1>
    // console.log(/<([^<>]+)>[\w\W]*<\/\1>/.exec('<h1><h1></h1></h1>'));

    // console.log(/(?:abc){2}/.exec('abcabc'));
    // console.log(RegExp.$1);

    // |
    // console.log(/12|34|56/.exec('12'));
    // console.log(/12|34|56/.exec('34'));
    // console.log(/12|34|56/.exec('56'));

    // 案例 匹配ip地址
    /**
     * \d 9
     * [1-9]\d 10-99
     * 1\d\d   100-199
     * 2[0-4]\d  200-249
     * 25[0-5]          250-255
     * */ 
    // console.log(/25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d/.exec('192'));

    // 案例2 匹配时间
    /**
     * 月：1-12    [1-9]|1[0-2]
     * 日：1-31    [1-9]|[1-2]\d|3[01] 
     * 小时:1-24   [1-9]|[1]\d|2[0-4]
     * 分钟：0-60   [1-9]|[1-5]\d|60
     * 秒钟：0-60
     * */ 

    // 断言 \b \B
    // console.log(/\ban\b/.test('an apple'));
    // console.log(/\ban\b/.test('anapple'));
    // console.log(/\ban/.test('an apple'));
    // console.log(/an\b/.test('an apple'));

    // ^ 判断是否是开头  $是否是结尾
    // console.log(/^an/.test('an apple'));
    // console.log(/e$/.test('an apple'));

    // 环视
    // 紧跟着b的a
    // console.log(/a(?=b)/.exec('ab'));
    // 不是紧跟
    // console.log(/a(?!b)/.exec('ab'));

    // 匹配模式 g i m
    console.log('1a,2a,3a'.replace(/a/, 'b'));
    console.log('1a,2a,3a'.replace(/a/g, 'b'));

    console.log(/a/i.exec('Ab'));

    console.log(/world$/m.test('hello world\n'));




  </script>
</body>

</html>